//===========================================================
//					es_app
//
//	Работа с приложением
//===========================================================

#include "es_app.h"
#include "es_spr.h"
#include "es_fnt.h"
#include "es_tps.h"

#include "xv_map.h"

// Подключаем библиотеки
#pragma comment( lib, "SDLmain.lib" )
#pragma comment( lib, "SDL_image.lib" )
#pragma comment( lib, "SDL_ttf.lib" )
#pragma comment( lib, "SDL.lib" )

// Максимальный допустимый фпс
const int FRAMES_PER_SECOND = 30;

// Конструктор приложения
cApplication::cApplication() 
{
	Running = true;
}

// При выполнении()
int cApplication::OnExecute() 
{
	// Если не удаётся инициализировать приложение - выходим
    if ( !OnInit() ) 
        return -1;

	// SDL событие
    SDL_Event Event; 
	// Регулятор фпс 
	Timer fps; 
	// Текущий кадр
	int frame = 0;

	// Основной цикл
    while ( Running ) 
	{
		// Запускаем таймер фпс
		fps.start();

		// Ловим SDL события
        while ( SDL_PollEvent(&Event) ) 
            OnEvent(&Event);

        OnLoop();
        OnRender();

		frame++;

		// Ограничитель по фпс
		if ( fps.get_ticks() < 1000 / FRAMES_PER_SECOND ) 
		{ 
			SDL_Delay((1000 / FRAMES_PER_SECOND) - fps.get_ticks()); 
		} 
    }

	// Очищаем за собой мусор
    OnCleanup();

    return 0;
}

// При инициализации
bool cApplication::OnInit() 
{
	// Включаем случайность
	srand(time(NULL));
	// Запускаем лог
	LogCreate();

	// Запускаем sdl
    if ( SDL_Init(SDL_INIT_EVERYTHING) < 0 ) 
	{
		LogWrite(" !!!ERROR!!! - Can't initialize SDL");
        return false;
	}

	// Создаём окно и sdl поверхность на нём, устанавливаем разрешение
    if ( (Surf_Display = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF)) == NULL )
	{
		LogWrite(" !!!ERROR!!! - Can't create SDL window");
        return false;
	}
	// Инициализируем SDL_ttf
	if ( TTF_Init() == -1 ) 
	{
		LogWrite(" !!!ERROR!!! - Can't load SDL_ttf");
		return false; 
	} 
	// Устанавливаем заголовок для окна
	SDL_WM_SetCaption("Legends of Adventurers alpha version", "Legends of Adventurers alpha version");

	// Отводим память под менеджер шрифтов и загружаем сами шрифты
	FontManager = new cFontManager();
	FontManager->LoadFont("data/fonts/pixcyr2.ttf", 28);

	// Отводим память под спрайтовый менеджер и загружаем сами спрайты
	SpriteManager = new cSpriteManager();
	SpriteManager->LoadSprite("data/sprites/BEAR.png");
	SpriteManager->LoadSprite("data/sprites/tree.png");
	SpriteManager->LoadSprite("data/sprites/grass.png");
	SpriteManager->LoadSprite("data/sprites/grass_daisies.png");
	SpriteManager->LoadSprite("data/sprites/grass_rflowers.png");
	SpriteManager->LoadSprite("data/sprites/grass_leaves.png");
	SpriteManager->LoadSprite("data/sprites/grass_slade.png");

	// Отводим память под карту и инициализируем её
	LocalMap = new cLocalMap(20, 15, "Изумрудная долина");

    return true;
}

// При получении события
void cApplication::OnEvent(SDL_Event* Event) 
{
	// Если пользователь закрывает окно - выходим
	if ( Event->type == SDL_QUIT )
        Running = false;
	// Нажатие клавиши
	if ( Event->type == SDL_KEYDOWN )
	{
		switch ( Event->key.keysym.sym ) 
		{	
			// F9 - выход
			case SDLK_F9: Running = false; break; 
		} 
	}
}

// При цикле
void cApplication::OnLoop() 
{
	//Проверяем, нажаты ли клавиши и двигаем игрока 
	Uint8 *keystates = SDL_GetKeyState(NULL); 

	if ( keystates[SDLK_UP ] ) 
		Player->Move(0, -1); 
	if ( keystates[SDLK_DOWN ] ) 
		Player->Move(0, 1);
	if ( keystates[SDLK_LEFT ] ) 
		Player->Move(-1, 0);
	if ( keystates[SDLK_RIGHT] ) 
		Player->Move(1, 0);
}

// При отрисовке
void cApplication::OnRender() 
{
	// Отрисовываем карту
	LocalMap->Draw();

	// Название карты
	FontManager->DrawText(320, 0, "%s", LocalMap->getName().c_str());

    SDL_Flip(Surf_Display);
}

// При очистке
void cApplication::OnCleanup() 
{
	// Очищаем память от нашей sdl поверхности
	SDL_FreeSurface(Surf_Display);
	// Очищаем память от наших менеджеров и их содержимого
	delete SpriteManager;
	delete FontManager;
	// Выходим из sdl
    SDL_Quit();
}

// Основная функция
int main(int argc, char* argv[]) 
{
    cApplication GameApplication;

    return GameApplication.OnExecute();
}